package com.plan.base.limiter;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class UserRateLimiter {
    private final Map<Long, RequestInfo> userRequestMap = new ConcurrentHashMap<>();
    /**
     * 时间窗口大小，单位为毫秒
     */
    private final long timeout;
    /**
     * 在给定的时间窗口内允许的最大请求数
     */
    private final int maxRequests;

    public UserRateLimiter(long timeout, TimeUnit timeUnit, int maxRequests) {
        this.timeout = timeUnit.toMillis(timeout);
        this.maxRequests = maxRequests;
    }

    public boolean isAllowed(Long userId) {
        String key = String.valueOf(userId);
        synchronized (key.intern()) {
            long now = System.currentTimeMillis();
            RequestInfo requestInfo = userRequestMap.get(userId);

            if (requestInfo == null) {
                userRequestMap.put(userId, new RequestInfo(now, 1));
                return true;
            }

            if ((now - requestInfo.timestamp) > timeout) {
                // 如果超过时间窗口，则重置计数器
                userRequestMap.put(userId, new RequestInfo(now, 1));
                return true;
            } else {
                // 检查是否超出最大请求数
                if (requestInfo.requestCount < maxRequests) {
                    userRequestMap.put(userId, new RequestInfo(now, requestInfo.requestCount + 1));
                    return true;
                } else {
                    return false;
                }
            }
        }
    }

    private static class RequestInfo {
        long timestamp;
        int requestCount;

        RequestInfo(long timestamp, int requestCount) {
            this.timestamp = timestamp;
            this.requestCount = requestCount;
        }
    }

}